package com.woniu.common;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class JwtUtil {
    @Value("${jwt.secret:defaultSecretKey}")
    private String secret;

    @Value("${jwt.expire:7200}") // 默认2小时
    private Long expire;

    @Value("${jwt.issuer:myapp}")
    private String issuer;

    /**
     * 生成JWT token
     */
    public String generateToken(Long userId, String username) {

        return JWT.create()
                .withIssuer(issuer) // 签发者
                .withSubject(userId.toString()) // 主题（通常放用户ID）
                .withClaim("username", username) // 自定义声明
                .withClaim("userId", userId)
                .withIssuedAt(new Date()) // 签发时间
                .withExpiresAt(new Date(System.currentTimeMillis() + expire * 1000)) // 过期时间
                .sign(Algorithm.HMAC256(secret)); // 签名算法
    }

    /**
     * 验证并解析token
     */
    public DecodedJWT verifyToken(String token) {
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret))
                    .withIssuer(issuer)
                    .build();
            return verifier.verify(token);
        } catch (Exception e) {
            throw new RuntimeException("Token验证失败", e);
        }
    }

    /**
     * 从token中获取用户ID
     */
    public Integer getUserIdFromToken(String token) {
        DecodedJWT jwt = verifyToken(token);
        return jwt.getClaim("userId").asInt();
    }

    /**
     * 从token中获取用户名
     */
    public String getUsernameFromToken(String token) {
        DecodedJWT jwt = verifyToken(token);
        return jwt.getClaim("username").asString();
    }

    /**
     * 检查token是否即将过期（用于token续期）
     */
    public boolean isTokenExpiringSoon(String token) {
        try {
            DecodedJWT jwt = verifyToken(token);
            Date expiresAt = jwt.getExpiresAt();
            long timeUntilExpiry = expiresAt.getTime() - System.currentTimeMillis();
            return timeUntilExpiry < (30 * 60 * 1000); // 30分钟内过期
        } catch (Exception e) {
            return true;
        }
    }
}
